package com.baibei.ebec.sdk.interceptor;

import android.text.TextUtils;

import com.baibei.sdk.ApiCode;
import com.baibei.sdk.ApiException;
import com.baibei.sdk.SdkConfig;
import com.baibei.sdk.TokenEvent;
import com.blankj.utilcode.utils.LogUtils;
import com.rae.swift.session.SessionManager;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.nio.charset.Charset;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okio.Buffer;
import okio.BufferedSource;

/**
 * 响应
 * Created by ChenRui on 2017/4/28 0028 15:21.
 */
public class ResponseInterceptor implements Interceptor {

    private final SdkConfig mSdkConfig;

    public ResponseInterceptor(SdkConfig config) {
        mSdkConfig = config;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        String body = bufferBody(response);
        // 请求错误的情况
        if (response.code() == 404) {
            throw new ApiException(ApiCode.NOT_FOUND, "没找到接口 " + request.url().encodedPath());
        }

        try {
            if (TextUtils.isEmpty(body) || "null".equalsIgnoreCase(body)) {
                logRequestError(request, body, String.valueOf(response.code()));
                throw new ApiException(ApiCode.SERVER_ERROR, "服务器没有返回任何数据");
            }
            LogUtils.i("api_response","后端成功返回数据:" + body);
            JSONObject object = new JSONObject(body);
            String code = object.has("code") ? object.getString("code") : null;
            String message = object.has("message") ? object.getString("message") : null;


            if (!response.isSuccessful()) {
                logRequestError(request, body, String.valueOf(response.code()));
                throw new ApiException(ApiCode.SERVER_ERROR, object.isNull("message") ? "服务器发生了一点问题" : message);
            }
            // 登录失效
            if (TextUtils.equals(code, ApiCode.TOKEN_EXPIRED)) {
                // 清除用户缓存
                SessionManager.getDefault().clear();
                // 发送事件
                EventBus.getDefault().post(new TokenEvent());
                logRequest(request, body, code);
                throw new ApiException(ApiCode.TOKEN_EXPIRED, "登录过期");
            }

            // 请求成功，但业务失败，TOKEN失效例外
            if (!TextUtils.equals(code, ApiCode.SUCCESS) && !TextUtils.equals(code, ApiCode.ACCESS_TOKEN_EXPIRED)) {
                logRequestError(request, body, code);
                throw new ApiException(code, object.isNull("message") ? "服务器返回错误，并且没有错误消息" : message);
            }

        } catch (JSONException e) {
            logRequestError(request, body, "APP_JSON_ERROR");
            throw new ApiException(ApiCode.JSON_ERROR, "数据解析错误", e);
        }

        return response;
    }

    private void logRequestError(Request request, String body, String code) {
        String requestBody = bufferRequestBody(request);
        LogUtils.e("api_response", "[" + code + "] " + request.url() + "\n" + request.headers() + "\n" + requestBody + "\n\nResponse Content:\n" + body);
    }

    private void logRequest(Request request, String body, String code) {
        String requestBody = bufferRequestBody(request);
        LogUtils.i("api_response", "[" + code + "] " + request.url() + "\n" + request.headers() + "\n" + requestBody + "\n\nResponse Content:\n" + body);
    }

    private String bufferBody(Response response) throws IOException {
        BufferedSource source = response.body().source();
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Charset charset = Charset.forName("UTF-8");
        return buffer.clone().readString(charset);
    }

    // 读请求参数的流
    private String bufferRequestBody(Request request) {
        try {
            if (request.body() != null && request.body().contentLength() > 0L) {
                Buffer e = new Buffer();
                request.body().writeTo(e);
                return e.readString(Charset.forName("UTF-8"));
            } else {
                return null;
            }
        } catch (IOException var3) {
            var3.printStackTrace();
            return null;
        }
    }
}
